"""
Generic state machine. 
"""

class StateMachine:
	def __init__(self, _debug=False):
		self.data = None
		self.states = []
		self.debug = _debug
	
	def push(self, _state):
		""" This method pushes a state onto the stack, making it the top and the method top()
	        will return this on the next call. 
		"""
		if self.debug:
			print "Debug >>> Pushing " + _state.name + " onto the stack."
		self.states.append(_state)
		
	def pop(self):
		""" This method removes the current state from the top of the stack. The state below it  will 
		    automaticly be retured by the next call to the top() method. returns the pop'd state
		"""
		try:
			states = self.top()
			self.states.pop(-1)
			return data
		except:
			print "stack empty"
			return None
		
	def count(self):
		""" Returns the number of states in the stack """
		return len(self.states)
		
	def top(self):
		""" returns the top state in the stack (the active one)  TODO: Must clean this code. The stack can
		    run out of states and this needs to be handled.
		"""
		try:
			return self.states[-1]
		except:
			print "stack empty"
			return None
			
	
	def dump(self):
		""" Dumps some data about the stack.
		"""
		try:
			print "Stack: length=", len(self.data)
			for x in self.states:
				print x.name, " run=", x.run
			topState = self.top()
			print "Top is " + topState.name
		except:
			print "stack empty"
		
	def ready(self):
		""" This method checks to see if the topstate has its ready flag set. """
		try:
			top_state = self.top()
			return top_state.run
		except:
			print "stack empty"
	
	# TODO: this is worthless. please remove.
	def need_init(self):
		""" Checks to see if the state needs to be inited.
		"""
		try:
			top_state = self.top()
			return top_state.needsInit
		except:
			print "stack empty"
		
	
	# TODO: This function needs to be able to look through the stack
	# and pick out states that are left behind or that have had their
	# ready flag changed by the current state.
	def cleanup(self):
		""" Cleans up the stack. """
		if self.ready():
			pass
	
	def __del__(self):
		""" generic destructor 
		"""
		pass
		
